package org.seeplnframework.skyeye.common.util;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.NumberUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.seeplnframework.skyeye.common.constants.SysConstant;
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.CompositePropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.support.StandardServletEnvironment;
import com.ctrip.framework.apollo.spring.config.ConfigPropertySource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.stream.Collectors;

@Slf4j
public class ConfigUtils {

    /**
     * 配置属性
     */
    private static final Properties properties = new Properties();

    /**
     * 获取String类型配置
     * @param key
     * @param defaultValue
     * @return
     */
    public static String getProperty(String key, String defaultValue) {
        if (StringUtils.isBlank(key)) {
            return defaultValue;
        }
        try {
            return properties.getProperty(key, defaultValue);
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * 获取Integer类型配置
     * @param key
     * @param defaultValue
     * @return
     */
    public static Integer getIntProperty(String key, Integer defaultValue) {
        if (StringUtils.isBlank(key)) {
            return defaultValue;
        }
        try {
            Object o = properties.getOrDefault(key, defaultValue);
            return NumberUtil.isInteger(o.toString()) ? Integer.parseInt(o.toString()) : defaultValue;
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * 获取Long类型配置
     * @param key
     * @param defaultValue
     * @return
     */
    public static Long getLongProperty(String key, Long defaultValue) {
        if (StringUtils.isBlank(key)) {
            return defaultValue;
        }
        try {
            Object o = properties.getOrDefault(key, defaultValue);
            return NumberUtil.isLong(o.toString()) ? Long.parseLong(o.toString()) : defaultValue;
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * 存储配置
     * @param key
     * @param value
     */
    public static void saveProperty(String key, String value) {
        if (StringUtils.isBlank(key) || value == null) {
            return;
        }
        try {
            properties.put(key, value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除配置
     * @param key
     */
    public static void removeProperty(String key) {
        if (StringUtils.isBlank(key)) {
            return;
        }
        try {
            properties.remove(key);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 初始化配置属性
     * @param applicationContext
     */
    public static void initProperties(ApplicationContext applicationContext) {
        if (applicationContext == null) {
            return;
        }
        Environment environment = applicationContext.getEnvironment();
        ConfigUtils.saveProperty(SysConstant.APPLICATION_NAME, environment.getProperty(SysConstant.APPLICATION_NAME));
        ConfigUtils.saveProperty(SysConstant.GIT_VERSION, environment.getProperty(SysConstant.GIT_VERSION));
        ConfigUtils.saveProperty(SysConstant.PROFILES_ACTIVE, environment.getProperty(SysConstant.PROFILES_ACTIVE));
        ConfigUtils.saveProperty(SysConstant.SYSTEM_DESC, environment.getProperty(SysConstant.SYSTEM_DESC));
        ConfigUtils.saveProperty(SysConstant.ALARM_ENABLED, environment.getProperty(SysConstant.ALARM_ENABLED));
        ConfigUtils.saveProperty(SysConstant.ALARM_WETALK, environment.getProperty(SysConstant.ALARM_WETALK));
        ConfigUtils.saveProperty(SysConstant.ALARM_SERIOUS_WETALK, environment.getProperty(SysConstant.ALARM_SERIOUS_WETALK));

        ConfigUtils.saveProperty(SysConstant.ALARM_STACKNUM, environment.getProperty(SysConstant.ALARM_STACKNUM));

        String whiteList = "";
        /**
         * 尝试把每个propertySource下这个key的值做merge
         * 这里做兜底逻辑 如果merge不到一起去 就保持现有取白名单的逻辑
         */
        try {
            if (environment instanceof StandardServletEnvironment) {
                MutablePropertySources mps = ((StandardServletEnvironment) environment).getPropertySources();
                PropertySource ps = mps.get("ApolloPropertySources");
                if (ps instanceof CompositePropertySource) {
                    whiteList = ((CompositePropertySource) ps)
                            .getPropertySources()
                            .stream()
                            .filter(it -> it instanceof ConfigPropertySource)
                            .map(it -> (ConfigPropertySource) it)
                            .map(it -> it.getProperty(SysConstant.ALARM_WHITE_LIST))
                            .filter(Objects::nonNull)
                            .map(it -> (String) it)
                            .filter(it -> StringUtils.isNotEmpty(it))
                            .map(String::trim)
                            .collect(Collectors.joining(","));
                }
            } else {
                whiteList = environment.getProperty(SysConstant.ALARM_WHITE_LIST);
            }
        } catch (Exception e) {
            whiteList = environment.getProperty(SysConstant.ALARM_WHITE_LIST);
        }
        ConfigUtils.saveProperty(SysConstant.ALARM_WHITE_LIST, whiteList);
        ConfigUtils.saveProperty(SysConstant.ALARM_AGGRE_WHITE_LIST, environment.getProperty(SysConstant.ALARM_AGGRE_WHITE_LIST));
        ConfigUtils.saveProperty(SysConstant.ALARM_NOTIFY_TIME, environment.getProperty(SysConstant.ALARM_NOTIFY_TIME));
        ConfigUtils.saveProperty(SysConstant.ALARM_NOTIFY_COUNT, environment.getProperty(SysConstant.ALARM_NOTIFY_COUNT));

        ConfigUtils.saveProperty(SysConstant.ALARM_URI_ELAPSED_TIME, environment.getProperty(SysConstant.ALARM_URI_ELAPSED_TIME));
        ConfigUtils.saveProperty(SysConstant.ALARM_URI_ELAPSED_COUNT, environment.getProperty(SysConstant.ALARM_URI_ELAPSED_COUNT));
        ConfigUtils.saveProperty(SysConstant.ALARM_URI_ELAPSED, environment.getProperty(SysConstant.ALARM_URI_ELAPSED));
        ConfigUtils.saveProperty(SysConstant.ALARM_URI_ELAPSED_GLOBAL, environment.getProperty(SysConstant.ALARM_URI_ELAPSED_GLOBAL));

        ConfigUtils.saveProperty(SysConstant.message_similarity_threshold, environment.getProperty(SysConstant.message_similarity_threshold));

//        Map<String, MQAdaptorConfig> mqAdaptorConfigMap = applicationContext.getBeansOfType(MQAdaptorConfig.class);
//        if (MapUtil.isNotEmpty(mqAdaptorConfigMap)) {
//            mqAdaptorConfigMap.forEach((beanName, mqAdaptorConfig) -> {
//                List<Map<String, String>> consumers = mqAdaptorConfig.getConsumers();
//                if (!CollectionUtils.isEmpty(consumers)) {
//                    properties.put(SysConstant.MQ_ADAPTOR_CONFIG_CONSUMERS, consumers);
//                }
//            });
//        }
    }

    /**
     * 获取应用名称
     * @return
     */
    public static String getApplicationName() {
        return getProperty(SysConstant.APPLICATION_NAME, "");
    }

    /**
     * 获取git版本
     * @return
     */
    public static String getGitVersion() {
        return getProperty(SysConstant.GIT_VERSION, "");
    }

    /**
     * 获取profile配置
     * @return
     */
    public static String getProfilesActive() {
        return getProperty(SysConstant.PROFILES_ACTIVE, "");
    }

    /**
     * 获取系统描述信息
     * @return
     */
    public static String getSystemDesc() {
        return getProperty(SysConstant.SYSTEM_DESC, "");
    }

    /**
     * 获取MQ消费端配置
     * @return
     */
    public static List<Map<String, String>> getMQAdaptorConfigConsumers() {
        try {
            Object obj = properties.get(SysConstant.MQ_ADAPTOR_CONFIG_CONSUMERS);
            return obj != null ? (List<Map<String, String>>) obj : null;
        } catch (Exception e) {
            return null;
        }
    }

}
